
#include <stdio.h>
#include "Nano100Series.h"
#include "GPIO_IIC.h"



#define DELAY_BIT	1		//for iic speed


/*---------------------------------------------------------------------------------------------------------*/
/* Global variables                                                                                        */
/*---------------------------------------------------------------------------------------------------------*/
uint8_t g_u8DeviceAddr;
uint8_t * g_au8TxData;
uint8_t g_u8RxData[5];
volatile uint16_t g_u8DataLen,g_u8data_p;
volatile uint8_t g_u8EndFlag = 0;

typedef void (*I2C_FUNC)(uint32_t u32Status);

static I2C_FUNC s_I2C0HandlerFn = NULL;
static I2C_FUNC s_I2C1HandlerFn = NULL;

uint8_t g_u8DeviceAddr1;
uint8_t * g_au8TxData1;
uint8_t g_u8RxData1[8];
volatile uint16_t g_u8DataLen1,g_u8data_p1;
volatile uint8_t g_u8EndFlag1 = 0;



/*---------------------------------------------------------------------------------------------------------*/
/*  I2C0 IRQ Handler                                                                                       */
/*---------------------------------------------------------------------------------------------------------*/
void I2C0_IRQHandler(void)
{
    uint32_t u32Status;

    // clear interrupt flag
    I2C0->INTSTS |= I2C_INTSTS_INTSTS_Msk;

    u32Status = I2C_GET_STATUS(I2C0);

    if (I2C_GET_TIMEOUT_FLAG(I2C0)) {
        /* Clear I2C0 Timeout Flag */
        I2C_ClearTimeoutFlag(I2C0);
    } else {
        if (s_I2C0HandlerFn != NULL)
            s_I2C0HandlerFn(u32Status);
    }
}

/*---------------------------------------------------------------------------------------------------------*/
/*  I2C Rx Callback Function                                                                               */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_MasterRx(uint32_t u32Status)
{
	
    if (u32Status == 0x08) {                    /* START has been transmitted and prepare SLA+W */
        I2C_SET_DATA(I2C0, (g_u8DeviceAddr )); /* Write SLA+W to Register I2CDAT */
        I2C_SET_CONTROL_REG(I2C0, I2C_SI);
    } else if (u32Status == 0x18) {             /* SLA+W has been transmitted and ACK has been received */
        I2C_SET_DATA(I2C0, g_au8TxData[0]);
        I2C_SET_CONTROL_REG(I2C0, I2C_SI);
    } else if (u32Status == 0x20) {             /* SLA+W has been transmitted and NACK has been received */
        I2C_SET_CONTROL_REG(I2C0, I2C_STA | I2C_STO | I2C_SI);
    } else if (u32Status == 0x28) {             /* DATA has been transmitted and ACK has been received */
        
        g_u8data_p=0;
        I2C_SET_CONTROL_REG(I2C0, I2C_STA | I2C_SI);
        
    } else if (u32Status == 0x10) {             /* Repeat START has been transmitted and prepare SLA+R */
        I2C_SET_DATA(I2C0, (g_u8DeviceAddr ) | 0x01);  /* Write SLA+R to Register I2CDAT */
        I2C_SET_CONTROL_REG(I2C0, I2C_SI);
    } else if (u32Status == 0x40) {             /* SLA+R has been transmitted and ACK has been received */
        I2C_SET_CONTROL_REG(I2C0, I2C_SI);
    } else if (u32Status == 0x58) {             /* DATA has been received and NACK has been returned */
    	//if(g_u8DataLen>g_u8data_p)
    		//{
		        g_u8RxData[0] = I2C_GET_DATA(I2C0);
		        I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI);
		        g_u8EndFlag = 1;
    		//}
		//else
			//{
			//	g_u8RxData[g_u8data_p++] = I2C_GET_DATA(I2C0);
		     //   I2C_SET_CONTROL_REG(I2C0, I2C_SI);
		       
			//}
    } else {
        /* TO DO */
        //printf("Status 0x%x is NOT processed\n", u32Status);
    }
}

/*---------------------------------------------------------------------------------------------------------*/
/*  I2C Tx Callback Function                                                                               */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_MasterTx(uint32_t u32Status)
{
    if (u32Status == 0x08) {                    /* START has been transmitted */
        I2C_SET_DATA(I2C0, g_u8DeviceAddr );  /* Write SLA+W to Register I2CDAT */
        I2C_SET_CONTROL_REG(I2C0, I2C_SI);
    } else if (u32Status == 0x18) {             /* SLA+W has been transmitted and ACK has been received */
        I2C_SET_DATA(I2C0, g_au8TxData[g_u8data_p++]);
        I2C_SET_CONTROL_REG(I2C0, I2C_SI);
    } else if (u32Status == 0x20) {             /* SLA+W has been transmitted and NACK has been received */
        I2C_SET_CONTROL_REG(I2C0, I2C_STA | I2C_STO | I2C_SI);
    } else if (u32Status == 0x28) {             /* DATA has been transmitted and ACK has been received */
        if (g_u8DataLen > g_u8data_p) {
            I2C_SET_DATA(I2C0, g_au8TxData[g_u8data_p++]);
            I2C_SET_CONTROL_REG(I2C0, I2C_SI);
        } else {
            I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI);
            g_u8EndFlag = 1;
        }
    } else {
        /* TO DO */
       // printf("Status 0x%x is NOT processed\n", u32Status);
    }
}




/********************************************************************/

void i2c_init(void)
{
	 /* Open I2C0 and set clock to 100k */
    I2C_Open(I2C0, 100000);

    

    /* Set I2C0 2 Slave Addresses */
    //I2C_SetSlaveAddr(I2C0, 0, 0x15, I2C_GCMODE_DISABLE);   /* Slave Address : 0x15 */
    //I2C_SetSlaveAddr(I2C0, 1, 0x35, I2C_GCMODE_DISABLE);   /* Slave Address : 0x35 */

    /* Enable I2C0 interrupt */
    I2C_EnableInt(I2C0);
    NVIC_EnableIRQ(I2C0_IRQn);

	

}

/********************************************************************/

uint8_t i2c_write(uint8_t slave_address, uint8_t *buffer, int byte_count)
{
	uint16_t count=0;
	g_u8DeviceAddr = slave_address;
	g_au8TxData=buffer;
	g_u8DataLen=byte_count;
	g_u8data_p=0;
	g_u8EndFlag = 0;
	/* I2C function to write data to slave */
    s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterTx;

    /* I2C as master sends START signal */
    I2C_SET_CONTROL_REG(I2C0, I2C_STA);

	/* Wait I2C Tx Finish */
    while (g_u8EndFlag == 0 &&count++<100)
		CLK_SysTickDelay(30);
	//delay(1);

}




/********************************************************************/

uint8_t i2c_read(uint8_t slave_address, uint8_t r_addr,uint8_t *buffer, int byte_count)
{
	uint8_t count=0;
	static uint8_t address[2];
	address[0]=r_addr;
	//address[1]=(uint8_t)(r_addr)&0xff;
	g_u8DeviceAddr = slave_address;
	g_au8TxData=address;
	g_u8DataLen=byte_count;
	g_u8data_p=0;
	g_u8EndFlag = 0;
	
	/* I2C function to write data to slave */
	s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterRx;

	/* I2C as master sends START signal */
	I2C_SET_CONTROL_REG(I2C0, I2C_STA);

	/* Wait I2C Tx Finish */
	while (g_u8EndFlag == 0&&count++<100)
		CLK_SysTickDelay(30);
	buffer[0]=g_u8RxData[0];
	buffer[1]=g_u8RxData[1];
	
}



/********************************************************************/

//void i2c_start(void)
//{	
//	
//	SDA=1;
//	delay(1);

//	SCK=1;
//	delay(1);	
//	  
//	SDA=0;;
//	delay(1);
//	     
//	SCK=0;
//	delay(1);
//}

/********************************************************************/

//uint8_t i2c_stop(void)
//{
//		  
//	SCK=0;
//	delay(1);

//	SDA=0;
//	delay(1);
//	    
//	SCK=1;
//	      
//	delay(1);
//	    
//	SDA=1;	
//	return(1);
//}

/********************************************************************/

void delay(int value)
{
	CLK_SysTickDelay(value);
}

/********************************************************************/


void write_reg_32(uint8_t slaveaddress,uint16_t address,uint32_t data)
{
	uint8_t buf[6];
	buf[0]=address>>8&0xff;
	buf[1]=address&0xff;
	buf[2]=data&0xff;
	buf[3]=data>>8&0xff;
	buf[4]=data>>16&0xff;
	buf[5]=data>>24&0xff;
	i2c_write(slaveaddress, buf,6);
}

void write_reg_16(uint8_t slaveaddress,uint8_t address,uint16_t data)
{
	uint8_t buf[4];
	//buf[0]=address>>8&0xff;
	buf[0]=address&0xff;
	buf[1]=data&0xff;
	buf[2]=data>>8&0xff;
	//buf[4]=data>>16&0xff;
	//buf[5]=data>>24&0xff;
	i2c_write(slaveaddress, buf,3);
}



//uint16_t read_reg_16(uint8_t slaveaddress,uint8_t address)
//{
//	uint8_t buf[4];
//	//buf[0]=address>>8&0xff;
//	buf[0]=address&0xff;
//	
//	//buf[4]=data>>16&0xff;
//	//buf[5]=data>>24&0xff;
//	i2c_write(slaveaddress, buf,1);
//	i2c_read(slaveaddress, buf,2);
//	return buf[0]<<8 |buf[1];
//}

void write_reg_8(uint8_t slaveaddress,uint8_t address,uint8_t data)
{
	uint8_t buf[2];
	buf[0]=address&0xff;
	buf[1]=data;
	//buf[2]=data&0xff;
	//buf[3]=data>>8&0xff;
	//buf[4]=data>>16&0xff;
	//buf[5]=data>>24&0xff;
	i2c_write(slaveaddress, buf,2);
}

uint8_t read_reg_8(uint8_t slaveaddress,uint8_t address)
{
	uint8_t buf[2];
	i2c_read(slaveaddress,address,buf,1);
	return buf[0];
}

#define SDA_1	PA0
#define SCK_1	PA1
#define SDA_2	PA10
#define SCK_2	PA11

#define SDA_3	PA0
#define SCK_3	PA1


/********************************************************************/



